package lion.framework.core.web.exception;

import java.io.File;
import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.exception.ExceptionUtils;

import lion.dev.web.WebUtil;
import lion.framework.core.conf.Config;
import lion.framework.core.conf.ConfigManager;
import lion.framework.core.util.AppPaths;

/**
 * 默认的异常处理器,会查找WEB-INF/404.jsp 或
 * 500.jsp,如果不存在则查找WEB-INF/error.jsp,如果文件都不存在，则直接输出错误信息
 *
 * <pre>
 * time   2013 2013-4-24 上午11:30:02
 * mail   hl_0074@sina.com
 * </pre>
 *
 * @author lion
 */
public class DefaultExceptionHandler implements IExceptionHandler {

	/**
	 * 1、检查 404页面 2、检查 500页面 3、检查 error.jsp页面
	 */

	private boolean dev = false;

	public DefaultExceptionHandler() {

		Config config = ConfigManager.getConfig("framework");
		dev = config.getBoolean("framework.devmode");
	}

	@Override
	public void handler(HttpServletRequest request, HttpServletResponse response, WebException exception) {

		if (exception == null) { return; }

		String file = "";
		if (exception.getStatus() == 404) {
			file = "/WEB-INF/404.jsp";
		} else if (exception.getStatus() == 500) {
			file = "/WEB-INF/500.jsp";
		} else {
			file = "/WEB-INF/error.jsp";
		}

		File f = new File(AppPaths.WEBROOT + file);
		if (!f.exists()) {
			file = "/WEB-INF/error.jsp";
			f = new File(FilenameUtils.separatorsToUnix(AppPaths.WEBROOT + file));
		}

		Throwable cause = exception;
		if (exception.getCause() != null) {
			cause = exception.getCause();
		}
		if (f.exists()) {
			forward(request, response, cause, file);
		} else {
			writeMessage(request, response, exception.getStatus(), cause);
		}
	}

	private void writeMessage(HttpServletRequest request, HttpServletResponse response, int status,
			Throwable exception) {

		String message = null;
		if (dev) {

			message = "<html><body>" + status + " " + exception.getMessage() + "<hr/><pre>"
					+ ExceptionUtils.getFullStackTrace(exception) + "</pre>";
		} else {
			message = ExceptionUtils.getRootCauseMessage(exception);
			if (StringUtils.isNotBlank(message)) {
				message = status + ":" + message;
			}
		}
		try {
			response.getWriter().write(message);
		} catch (IOException e) {
		}
	}

	private void forward(HttpServletRequest request, HttpServletResponse response, Throwable exception, String file) {

		WebUtil.exposeForwardAttribute(request);
		WebUtil.exposeErrorAttribute(request, exception);

		try {
			request.getRequestDispatcher(file).forward(request, response);
		} catch (Exception e) {
		}
	}

}
